package grasshopper.gcm.db;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.persistence.annotations.ConversionValue;
import org.eclipse.persistence.annotations.Convert;
import org.eclipse.persistence.annotations.ObjectTypeConverter;

/**
 * <pre>
 * type: determined by subscriptions types
 * status: active, not active, might be more defined by user.
 * complete: company record is completre when:
 *    - legal address is exists and is complete
 *    - company.name is not null
 *    - country and language are not null
 * </pre>
 *
 * Valid Company MUST have one and only one legal address. There could be many addresses of
 * same kind but not a legal one.
 * 
 * @author piokob
 */
@Entity
@Table(name = "COMPANY_CO")
public class Company implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "COCOMPANYID")
    private Long companyId;
    @Column(name = "CONAME", length = 60)
    private String name;
    @Column(name = "CODUNSNO", length = 10)
    private String dunsNumber;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "company")
    List<CompanyAddress> addresses = new ArrayList<CompanyAddress>();
    @Column(name = "COREGNO", length = 20)
    private String registrationNumber;
    @Column(name = "COVATNO", length = 20)
    private String vatNumber;
    @Column(name = "COSTATUS", columnDefinition="char(3) not null")
    //TODO add checkin constraits for ('ACT', 'NAC', 'IMP')
    @ObjectTypeConverter(name = "status", dataType = String.class,
    objectType = Company.CompanyStatus.class, conversionValues = {
        @ConversionValue(dataValue = "ACT", objectValue = "Active"),
        @ConversionValue(dataValue = "NAC", objectValue = "NotActive"),
        @ConversionValue(dataValue = "IMP", objectValue = "Imported")})
    @Convert(value = "status")
    private CompanyStatus status = CompanyStatus.Active;
    // default 0
    // 0 - not checked
    // 1 - not duplicate
    // 2 - duplicate
    @Column(name = "CODUPSTATUS", columnDefinition = "char(4) not null")
    //TODO add check in constraint for ('NCHK', 'NDUP', 'DUPL')
    @ObjectTypeConverter(name = "duplicateStatus", dataType = String.class,
    objectType = Company.DuplicateStatus.class, conversionValues = {
        @ConversionValue(dataValue = "NCHK", objectValue = "NotChecked"),
        @ConversionValue(dataValue = "NDUP", objectValue = "NotDuplicate"),
        @ConversionValue(dataValue = "DUPL", objectValue = "Duplicate")})
    @Convert("duplicateStatus")
    private DuplicateStatus duplicateStatus = DuplicateStatus.NotChecked;
    // if null duplicateStatus has to be 0 or 1;
    // other
    // null - not checked
    // id=duplicateOf - not duplicate
    // other - tpid of dupplacite of
    @ManyToOne
    @JoinColumn(name = "CODUPLICATEOF")
    private Company duplicateOf;

    public Long getCompanyId() {
        return companyId;
    }

    public void setCompanyId(Long companyId) {
        this.companyId = companyId;
    }
    //--------------------------------------------------------------------------

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDunsNumber() {
        return dunsNumber;
    }

    public void setDunsNumber(String dunsNumber) {
        this.dunsNumber = dunsNumber;
    }

    public List<CompanyAddress> getAddresses() {
        return addresses;
    }

    public void setAddresses(List<CompanyAddress> addresses) {
        this.addresses = addresses;
    }

    public String getRegistrationNumber() {
        return registrationNumber;
    }

    public void setRegistrationNumber(String registrationNumber) {
        this.registrationNumber = registrationNumber;
    }

    public String getVatNumber() {
        return vatNumber;
    }

    public void setVatNumber(String vatNumber) {
        this.vatNumber = vatNumber;
    }

    public CompanyStatus getStatus() {
        return status;
    }

    public void setStatus(CompanyStatus status) {
        this.status = status;
    }

    public DuplicateStatus getDuplicateStatus() {
        return duplicateStatus;
    }

    public void setDuplicateStatus(DuplicateStatus duplicateStatus) {
        this.duplicateStatus = duplicateStatus;
    }

    public Company getDuplicateOf() {
        return duplicateOf;
    }

    public void setDuplicateOf(Company tp) {
        duplicateOf = tp;
    }
    //--------------------------------------------------------------------------

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (companyId != null ? companyId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Company)) {
            return false;
        }
        Company other = (Company) object;
        if ((this.companyId == null && other.companyId != null)
            || (this.companyId != null && !this.companyId.equals(other.companyId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "grasshopper.gcm.db.Company[companyId=" + companyId + "]";
    }

    //----------------------------------------------------------------------------------------------
    public enum DuplicateStatus {

        NotChecked, NotDuplicate, Duplicate;
    }

    public enum CompanyStatus {

        Active, NotActive, Imported;
    }
}
